//package com.pavisoft.irecipe.osxgui;

import com.apple.cocoa.foundation.*;
import com.apple.cocoa.application.*;
import com.pavisoft.irecipe.*;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;

public class AppController {

    public NSTableView categoryViewer; /* IBOutlet */
    public NSTableView recipeViewer; /* IBOutlet */
    public NSMenuItem openRecipeMenuItem; /* IBOutlet */
    public NSMenuItem delCatMenuItem; /* IBOutlet */
    public NSMenuItem delRecipeMenuItem; /* IBOutlet */
    public NSMenuItem mnuNewCat;
    public NSMenuItem mnuNewRec;
    public NSWindow window; /* IBOutlet */
    public static NSMenuItem mnuShowHideDrawer;
    
    private CategoryViewerDataSource categoryViewDS;
    private RecipeViewerDataSource recipeViewDS;
    private RecipeViewerDelegate recipeViewerDelegate;
    private CategoryViewerDelegate categoryViewerDelegate;
    
    private final String CATEGORY_PBOARD_TYPE = "iRecipe!CATEGORY";
    private final String RECIPE_PBOARD_TYPE = "iRecipe!RECIPE";
    
    //TODO: Put somewhere sensible (~/Library/Application Support/iRecipe?)
    private final File LIB_FILE = new File("iRecipeLIBRARY.xml");
    private RecipeLibrary library = new RecipeLibrary(LIB_FILE);

    private NSSelector recipeDoubleClickSelector =
            new NSSelector("recipeDoubleClick", new Class[] { Object.class });
    
    public AppController()
    {
        categoryViewDS = new CategoryViewerDataSource();
        recipeViewDS = new RecipeViewerDataSource();
        recipeViewerDelegate = new RecipeViewerDelegate();
        categoryViewerDelegate = new CategoryViewerDelegate();
    }

    protected void awakeFromNib() {
        recipeViewer.setTarget(this);
        recipeViewer.setDelegate(recipeViewerDelegate);
        openRecipeMenuItem.setEnabled(false);
        delCatMenuItem.setEnabled(false);
        delRecipeMenuItem.setEnabled(false);
        openRecipeMenuItem.setAction(recipeDoubleClickSelector);
        categoryViewer.setDelegate(categoryViewerDelegate);
        categoryViewer.setDataSource(categoryViewDS);
        recipeViewer.setDataSource(recipeViewDS);
        recipeViewer.setDoubleAction(recipeDoubleClickSelector);
        recipeViewer.registerForDraggedTypes(new NSArray(RECIPE_PBOARD_TYPE));
        categoryViewer.registerForDraggedTypes(
                new NSArray(new Object[] { CATEGORY_PBOARD_TYPE, RECIPE_PBOARD_TYPE }));
    }
    
    public void _setMnuShowHideDrawer(NSMenuItem object)
    {
        AppController.mnuShowHideDrawer = object;
    }
    
    public void recipeSingleClick(Object sender) { /* IBAction */
    
    }

    public void recipeDoubleClick(Object sender) {
        NSIndexSet selIndices = recipeViewer.selectedRowIndexes();
        if (sender instanceof NSTableView && recipeViewer.clickedRow() == -1)
        {   // no row clicked (just somewhere in table), so ignore
            return;
        }
        if (selIndices.firstIndex() == NSIndexSet.NotFound)
        {
            //nothing selected, so ignore
            return;
        }

        for (int index = 0;
             index <= selIndices.lastIndex();
             index++)
        {
            if (selIndices.containsIndex(index))
            {
                Recipe recipe = library.getRecipeGroups()[getSelectedRecipeGroupIdx()].getRecipes()[index];
                RecipeWindowController rwc = new RecipeWindowController(recipe, library, recipeViewer);
                rwc.showWindow(this);
            }
        }        
    }
    
    public void addCategory(Object sender) { /* IBAction */
        //I18N: Will need to load this string from somewhere else
        library.addRecipeGroup(new RecipeGroup("New Category"));
        categoryViewer.reloadData();
        categoryViewer.selectRowIndexes(new NSIndexSet(categoryViewer.numberOfRows()-1), false);
        categoryViewer.editLocation(0, categoryViewer.numberOfRows() - 1, null, true);
    }

    public void addRecipe(Object sender) { /* IBAction */
        Recipe r = new Recipe();
        library.getRecipeGroups()[getSelectedRecipeGroupIdx()].addRecipe(r);
        RecipeWindowController rwc = new RecipeWindowController(r, library, recipeViewer);
        rwc.showWindow(this);
    }

    public void deleteCategory(Object sender) { /* IBAction */
        int i = this.getSelectedRecipeGroupIdx();
        if (i != -1)
        {
            this.library.removeRecipeGroup(library.getRecipeGroups()[i]);
        }
        categoryViewer.reloadData();
    }
    
    /** Returns index of currently selected RecipeGroup in the UI, or -1 if
     *  none selected. */
    public int getSelectedRecipeGroupIdx()
    {
        int i = categoryViewer.selectedRow();
        return i;        
    }

    public int getSelectedRecipeIdx()
    {
        int i = recipeViewer.selectedRow();
        return i;
    }
    
    public void deleteRecipe(Object sender) { /* IBAction */
        int i = getSelectedRecipeGroupIdx();
        int j = getSelectedRecipeIdx();
        if (i != -1 && j != -1)
        {
            library.getRecipeGroups()[i].removeRecipe(j);
        }
        recipeViewer.reloadData();
    }
	
    public void selectAll(Object sender) { /* IBAction */
        System.out.println("Select all");
    }
    
    public boolean becomeFirstResponder()
    {
        System.out.println("first resp");
        return true;
    }
    
    public boolean validateMenuItem(NSMenuItem menuItem)
    {
        if (menuItem.equals(delCatMenuItem))
        {
            if (categoryViewer.selectedRow() != -1)
                return true;
        }
        else if (menuItem.equals(delRecipeMenuItem))
        {
            if (recipeViewer.selectedRow() != -1)
                return true;            
        }
        else if (menuItem.equals(openRecipeMenuItem))
        {
            if (recipeViewer.selectedRow() != -1)
                return true;              
        }
        else if (menuItem.equals(mnuNewCat) || menuItem.equals(mnuNewRec))
        {
            return true;
        }
        
        return false;
    }
    
    public boolean applicationShouldTerminate(NSApplication sender)
    {
        library.saveLibrary();
        return true;
    }
    
    public void toggleToolbarShown(NSObject sender)
    {
        System.out.println("Toggling!");
    }
    
    private class RecipeViewerDelegate
    {        
        public void tableViewSelectionDidChange(NSNotification notification)
        {
        }
        
        public boolean becomeFirstResponder()
        {
            System.out.println("first resp11111");
            return true;
        }
    }

    private class CategoryViewerDelegate
    {        
        public void tableViewSelectionDidChange(NSNotification notification)
        {
            recipeViewer.reloadData();
            int selRow = recipeViewer.selectedRow();
            boolean state = true;
            if (selRow == - 1) state = false;
            delCatMenuItem.setEnabled(state);            
        }
        
    }

            
    private class CategoryViewerDataSource
    {
        public int numberOfRowsInTableView(NSTableView nSTableView)
        {
            return library.getRecipeGroups().length;
        }
        
//        public void keyDown(Object sender)
//        {
//            System.out.println("here!");
//        }
//                
//        public void delete(Object sender)
//        {
//            System.out.println("del!");
//        }
        
        public Object tableViewObjectValueForLocation(NSTableView nSTableView, NSTableColumn nSTableColumn, int row)
        {
            return library.getRecipeGroups()[row].getName();
        }

        public void tableViewSetObjectValueForLocation(NSTableView nSTableView, Object object, NSTableColumn nSTableColumn, int row)
        {
            library.getRecipeGroups()[row].setName(object.toString());
        }

        public boolean tableViewWriteRowsToPasteboard(NSTableView tableView, NSIndexSet indexSet, NSPasteboard pboard)
        {
            if (library.getRecipeGroups().length <= 1) return false;
            
            pboard.declareTypes(new NSArray(CATEGORY_PBOARD_TYPE), this);
            pboard.setDataForType(NSKeyedArchiver.archivedDataWithRootObject(indexSet),
                    CATEGORY_PBOARD_TYPE);
            return true;
        }

        public int tableViewValidateDrop(NSTableView tableView, NSDraggingInfo info, int row, int operation)
        {
            if (info.draggingPasteboard().types().containsObject(RECIPE_PBOARD_TYPE))
            {
                if (operation == NSTableView.DropOn)
                {
                    return NSDraggingInfo.DragOperationMove;
                }
            }
            else if (info.draggingPasteboard().types().containsObject(CATEGORY_PBOARD_TYPE))
            {
                if (operation == NSTableView.DropOn)
                {
                    return NSDraggingInfo.DragOperationNone;
                }
                return NSDraggingInfo.DragOperationMove;
            }
            // if neither recipe nor category type (or none of above satisfied), can't handle, so don't allow
            return NSDraggingInfo.DragOperationNone;
        }

        public boolean tableViewAcceptDrop(NSTableView tableView, NSDraggingInfo info, int row, int operation)
        {   
            if (info.draggingPasteboard().types().containsObject(RECIPE_PBOARD_TYPE))
            {
                NSData data = info.draggingPasteboard().dataForType(RECIPE_PBOARD_TYPE);
                Object obj = NSKeyedUnarchiver.unarchiveObjectWithData(data);
                NSIndexSet rows = (NSIndexSet)obj;
                for (int idx = rows.firstIndex(); idx != NSIndexSet.NotFound; idx = rows.indexGreaterThanIndex(idx))
                {
                    Recipe r = library.getRecipeGroups()[getSelectedRecipeGroupIdx()].getRecipe(idx);
                    library.getRecipeGroups()[row].addRecipe(r);
                    library.getRecipeGroups()[getSelectedRecipeGroupIdx()].removeRecipe(r);                 
                }
                categoryViewer.reloadData();
                recipeViewer.reloadData();
                return true;
            }
            else if (info.draggingPasteboard().types().containsObject(CATEGORY_PBOARD_TYPE))
            {
                NSData data = info.draggingPasteboard().dataForType(CATEGORY_PBOARD_TYPE);
                Object obj = NSKeyedUnarchiver.unarchiveObjectWithData(data);
                NSIndexSet rows = (NSIndexSet)obj;
                for (int idx = rows.firstIndex(); idx != NSIndexSet.NotFound; idx = rows.indexGreaterThanIndex(idx))
                {
                    library.moveRecipeGroup(idx, row);
                }
                categoryViewer.reloadData();
                recipeViewer.reloadData();
                return true;
            }
            // just in case none of above did occur:
            return false;        
        }        
    }
    
    private class RecipeViewerDataSource
    {
        public int numberOfRowsInTableView(NSTableView nSTableView)
        {
            if (categoryViewer.selectedRow() == -1) return 0;
            return library.getRecipeGroups()[categoryViewer.selectedRow()].getRecipes().length;
        }

        public Object tableViewObjectValueForLocation(NSTableView nSTableView, NSTableColumn nSTableColumn, int row)
        {
            String s = "";          
            if (nSTableColumn == nSTableView.tableColumns().objectAtIndex(0))
            {
                s = library.getRecipeGroups()[categoryViewer.selectedRow()].getRecipes()[row].getName();
            }
            else if (nSTableColumn == nSTableView.tableColumns().objectAtIndex(1))
            {
                s = library.getRecipeGroups()[categoryViewer.selectedRow()].getRecipes()[row].getDescription();
            }
            return s;
        }

        public void tableViewSetObjectValueForLocation(NSTableView nSTableView, Object object, NSTableColumn nSTableColumn, int i)
        {
        }
        
        public boolean tableViewWriteRowsToPasteboard(NSTableView tableView, NSIndexSet indexSet, NSPasteboard pboard)
        {
            if (library.getRecipeGroups().length <= 1) return false;
            
            pboard.declareTypes(new NSArray(RECIPE_PBOARD_TYPE), this);
            pboard.setDataForType(NSKeyedArchiver.archivedDataWithRootObject(indexSet),
                    RECIPE_PBOARD_TYPE);
            return true;
        }

        public int tableViewValidateDrop(NSTableView tableView, NSDraggingInfo info, int row, int operation)
        {
            if (operation == NSTableView.DropOn)
            {
                return NSDraggingInfo.DragOperationNone;
            }
            return NSDraggingInfo.DragOperationMove;               
        }

        public boolean tableViewAcceptDrop(NSTableView tableView, NSDraggingInfo info, int row, int operation)
        {               
            NSData data = info.draggingPasteboard().dataForType(RECIPE_PBOARD_TYPE);
            Object obj = NSKeyedUnarchiver.unarchiveObjectWithData(data);
            NSIndexSet rows = (NSIndexSet)obj;
            for (int idx = rows.firstIndex(); idx != NSIndexSet.NotFound; idx = rows.indexGreaterThanIndex(idx))
            {
                library.getRecipeGroups()[getSelectedRecipeGroupIdx()].moveRecipe(idx, row);
            }
            categoryViewer.reloadData();
            recipeViewer.reloadData();
            return true;
        }        
    }

}
